//
//  Created by Mike on 26/05/2018.
//  Copyright © 2018 Bohemian Coding. All rights reserved.
//

#import <Foundation/Foundation.h>


#pragma mark Making Vectors

/// Creates a vector from a to b.
CGVector BCVectorFromPointToPoint(CGPoint a, CGPoint b);


#pragma mark Querying Vectors

/// Calculates the magnitude (length) of a vector. Note that this involves a square root operation
/// so is a bit slow, and you're often better off calculating magnitude^2 yourself and working with
/// that.
CGFloat BCVectorGetMagnitude(CGVector v);


#pragma mark Operating Upon Vectors

/// Dead simple, inverts all components of the vector.
CG_INLINE CGVector BCVectorReverse(CGVector v) {
  return CGVectorMake(-v.dx, -v.dy);
}

/// Adds together two vectors.
CG_INLINE CGVector BCVectorAdd(CGVector v1, CGVector v2) {
  return CGVectorMake(v1.dx + v2.dx, v1.dy + v2.dy);
}

/// Calculates the dot product of two vectors.
CG_INLINE CGFloat BCVectorDotProduct(CGVector v1, CGVector v2) {
  return v1.dx * v2.dx + v1.dy * v2.dy;
}

/// Returns the vector resulting from a transformation of an existing vector.
CG_INLINE CGVector BCVectorApplyAffineTransform(CGVector vector, CGAffineTransform t) {
  CGVector v;
  v.dx = (t.a * vector.dx + t.c * vector.dy);
  v.dy = (t.b * vector.dx + t.d * vector.dy);
  return v;
}


#pragma mark Manipulating Points Using Vectors

/// Translates the point, \c p by the vector, \c v.
CGPoint BCPointAddVector(CGPoint p, CGVector v);

/// As above, but subtracts the vector instead of adding it. Equivalent to reversing \c v and then
/// adding that to the point.
CGPoint BCPointSubtractVector(CGPoint p, CGVector v);
